/*
 * @Author: duapple
 * @Date: 2021-11-07 04:03:50
 * @LastEditTime: 2021-11-30 20:56:41
 * @LastEditors: duapple
 * @Description: Add description
 * @FilePath: /genmake/main.go
 * Copyright (c) 2011 duapple - All rights reserved.
 */
package main

import (
	"errors"
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"

	file "gitee.com/duapple/go_config_file"
)

type Make_flag struct {
	Flag        string
	FlagDefault bool
	Description string
	ConfFile    string
	Makefile    string
	Value       *bool
}

type Make_flag_reg []Make_flag

const (
	GENMAKE_CONF_KEY            = "genmake_conf"
	GENMAKE_CONFIG_FILE_DEFAULT = "genmake_conf.json"
)

var GENMAKE_CONF_FILE = GENMAKE_CONFIG_FILE_DEFAULT
var tool_dir string
var work_dir string

var flag_register = Make_flag_reg{}

func main() {
	fmt.Println(`##########################
       genmake tool
##########################`)

	GENMAKE_CONF_FILE = GENMAKE_CONFIG_FILE_DEFAULT

	exe, _ := os.Executable()
	tool_dir, _ = filepath.Abs(filepath.Dir(exe))
	work_dir, _ = os.Getwd()

	file.ReadFile(filepath.Join(tool_dir, "config", GENMAKE_CONF_FILE))
	file.Read(&flag_register, GENMAKE_CONF_KEY)
	// file.Write(flag_register, GENMAKE_CONF_KEY)

	flag_register.register_flag()
	if len(os.Args) <= 1 {
		flag.Usage()
	}

	flag_register.genmake()
}

func (reg *Make_flag_reg) register_flag() {
	for i := 0; i < len(*reg); i++ {
		(*reg)[i].Value = flag.Bool((*reg)[i].Flag, (*reg)[i].FlagDefault, (*reg)[i].Description)
	}
	flag.Parse()
}

func (reg *Make_flag_reg) genmake() error {

	for i := 0; i < len(*reg); i++ {
		if *(*reg)[i].Value {

			dst := filepath.Join(work_dir, (*reg)[i].Makefile)
			if _, err := os.Stat(dst); err == nil {
				fmt.Println("Current dir ", (*reg)[i].Makefile, " has existed. Overwrite ?")
				var input string
				for !(input == "Y") || !(input == "N") {
					fmt.Println("Please Enter [Y/N]")
					fmt.Scanf("%s\n", &input)
					if input == "N" {
						fmt.Println((*reg)[i].Makefile, " is not generated. \n Quit")
						return errors.New("genmake create " + (*reg)[i].Makefile + " failed")
					} else if input == "Y" {
						break
					}
				}
			}

			config_dir := filepath.Join(tool_dir, "config", "makefile", filepath.Clean((*reg)[i].ConfFile))

			if _, err := copy_file(config_dir, dst); err != nil {
				fmt.Println(config_dir)
				fmt.Println("Generate FAILED. ", (*reg)[i].Makefile, " is not generated.")
				return errors.New("genmake create " + (*reg)[i].Makefile + " failed")
			}

			fmt.Println("Generate ", (*reg)[i].Makefile, " success.")
		}
	}

	return nil
}

func copy_file(src, dst string) (int64, error) {
	sourceFileStat, err := os.Stat(src)
	if err != nil {
		return 0, err
	}
	if !sourceFileStat.Mode().IsRegular() {
		return 0, fmt.Errorf("%s is not a regular file", src)
	}

	source, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	defer source.Close()

	destination, err := os.Create(dst)
	if err != nil {
		return 0, err
	}
	defer destination.Close()

	nBytes, err := io.Copy(destination, source)
	return nBytes, err
}
